import random
import time
import unittest

from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol

from hbase import Hbase, ttypes


transport = TTransport.TBufferedTransport( TSocket.TSocket('localhost', 9090))
protocol = TBinaryProtocol.TBinaryProtocol(transport)


class HbaseTest(unittest.TestCase):

    client = Hbase.Client(protocol)
    test_table = 'test_table'


    def cleanup(self):
        for t in self.client.getTableNames():
            if t == self.test_table:
                if self.client.isTableEnabled(t):
                    self.client.disableTable(t)
                self.client.deleteTable(t)


    def setUp(self):
        transport.open()
        self.cleanup()


    def tearDown(self):
        transport.close()


    def test_create_delete(self):
        client = self.client
        test_table = self.test_table

        columns = [Hbase.ColumnDescriptor({'name': 'foo:'}),
                   Hbase.ColumnDescriptor({'name': 'bar:'})]
        client.createTable(test_table, columns)
        self.assertTrue(test_table in client.getTableNames())

        self.assertRaises(ttypes.AlreadyExists,
            client.createTable, test_table, columns)

        self.assertTrue(client.isTableEnabled(test_table))
        self.assertRaises(Exception, client.deleteTable, test_table)

        client.disableTable(test_table)
        self.assertFalse(client.isTableEnabled(test_table))
        client.deleteTable(test_table)
        self.assertTrue(test_table not in client.getTableNames())


    def test_mutate(self):
        client = self.client
        test_table = self.test_table

        client.createTable(test_table,
            [Hbase.ColumnDescriptor({'name': 'nis:'}),
             Hbase.ColumnDescriptor({'name': 'mail:'})])

        client.mutateRow(test_table, 'carlos',
            [Hbase.Mutation({'column': 'nis:uid', 'value': '42'}),
             Hbase.Mutation({'column': 'nis:gid', 'value': '42'}),
             Hbase.Mutation({'column': 'nis:gecos',
                             'value':  'Carlos Valiente'}),
             Hbase.Mutation({'column': 'nis:passwd', 'value': 'sup3rs3cr3r'}),
             Hbase.Mutation({'column': 'nis:home', 'value':  '/home/carlos'}),
             Hbase.Mutation({'column': 'nis:shell', 'value': '/bin/bash'}),
             Hbase.Mutation({'column': 'mail:address',
                             'value':  'carlos.valiente@ecmwf.int'}),
             Hbase.Mutation({'column': 'mail:alias',
                             'value':  'cvaliente@ecmwf.int'}),])

        row = client.getRow(test_table, 'carlos')
        self.assertEquals(row.row, 'carlos')
        self.assertEquals(row.columns['nis:uid'].value, '42')
        self.assertEquals(row.columns['nis:gid'].value, '42')
        self.assertEquals(row.columns['nis:gecos'].value, 'Carlos Valiente')
        self.assertEquals(row.columns['nis:passwd'].value, 'sup3rs3cr3r')
        self.assertEquals(row.columns['nis:passwd'].value, 'sup3rs3cr3r')
        self.assertEquals(row.columns['nis:home'].value, '/home/carlos')
        self.assertEquals(row.columns['nis:shell'].value, '/bin/bash')
        self.assertEquals(row.columns['mail:address'].value,
            'carlos.valiente@ecmwf.int');
        self.assertEquals(row.columns['mail:alias'].value,
            'cvaliente@ecmwf.int');
    

    def test_performance(self):
        client = self.client
        test_table = self.test_table

        client.createTable(test_table,
            [Hbase.ColumnDescriptor({'name': 'nis:'}),
             Hbase.ColumnDescriptor({'name': 'mail:'})])

        print '\nPerformance indicators:'

        n_mutations = 1000
        start = time.time()
        for i in xrange(0, n_mutations):
            client.mutateRow(test_table, 'user-%d' % i,
                [Hbase.Mutation({'column': 'nis:uid', 'value': str(i)}),
                 Hbase.Mutation({'column': 'nis:gid', 'value': '42'}),
                 Hbase.Mutation({'column': 'nis:gecos',
                                 'value':  'Carlos Valiente'}),
                 Hbase.Mutation({'column': 'nis:passwd', 'value': 'sup3rs3cr3r'}),
                 Hbase.Mutation({'column': 'nis:home', 'value':  '/home/carlos'}),
                 Hbase.Mutation({'column': 'nis:shell', 'value': '/bin/bash'}),
                 Hbase.Mutation({'column': 'mail:address',
                                 'value':  'carlos.valiente@ecmwf.int'}),
                 Hbase.Mutation({'column': 'mail:alias',
                                 'value':  'cvaliente@ecmwf.int'}),])
        stop = time.time()
        print '    client.mutateRow():  %f msec (average of %d calls)' % \
            (((stop - start) / n_mutations) * 1000, n_mutations)

        mutations = []
        for i in xrange(0, n_mutations):
            mutations.append(Hbase.BatchMutation({'row': 'batch-user-%d' % i,
                'mutations': [Hbase.Mutation({'column': 'nis:uid',
                                              'value':  str(i)}),
                              Hbase.Mutation({'column': 'nis:gid',
                                              'value':  '42'}),
                              Hbase.Mutation({'column': 'nis:gecos',
                                              'value':  'Carlos Valiente'}),
                              Hbase.Mutation({'column': 'nis:passwd',
                                              'value':  'sup3rs3cr3r'}),
                              Hbase.Mutation({'column': 'nis:home',
                                              'value':  '/home/carlos'}),
                              Hbase.Mutation({'column': 'nis:shell',
                                              'value':  '/bin/bash'}),
                              Hbase.Mutation({'column': 'mail:address',
                                              'value':  'carlos.valiente@ecmwf.int'}),
                              Hbase.Mutation({'column': 'mail:alias',
                                              'value':  'cvaliente@ecmwf.int'})]}))
        start = time.time()
        client.mutateRows(test_table, mutations)
        stop = time.time()
        print '    client.mutateRows(): %f msec (%d batch mutations)' % \
            (((stop - start) / n_mutations) * 1000, n_mutations)

        rows = ['user-%d' % i for i in xrange(0, n_mutations)]
        rows.extend('batch--%d' % i for i in xrange(0, n_mutations))
        random.shuffle(rows)

        n_rows = len(rows)
        start = time.time()
        for row in rows:
            client.getRow(test_table, row)
        stop = time.time()
        print '    client.getRow():  %f msec (average of %d calls)' % \
            (((stop - start) / n_rows) * 1000, n_rows)
